/**
 * Implementation of the Frame interface.
 *
 * @author Timothy Flynn (trflynn@wpi.edu)
 * @version April 10, 2012
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <string>
using std::string;

#include "Frame.h"

/**
 * Default constructor. Leave all fields blank?
 */
Frame::Frame() {
	// TODO
}

/**
 * Constructor from a string containing all information.
 */
Frame::Frame(char *str) {
	// Byte 0 is 0x7E - ignore for now?
	string *s = new string(str);
	str[1] == '0' ? this->type = DATA : this->type = ACK;
	str[2] == '0' ? this->end = false : this->end = true;
	this->seq = (short)atoi(s->substr(3, SEQ_NUM_LEN).c_str());
	this->ack = (short)atoi(s->substr(8, ACK_NUM_LEN).c_str());
	this->crc = (unsigned short)atoi(s->substr(13, CRC_LEN).c_str());
	this->length = (short)atoi(s->substr(18, DATA_LEN).c_str());
	this->data = (char *)malloc((this->length + 1) * sizeof(char));
	memcpy(this->data, (char *)s->substr(21, this->length).c_str(), this->length);
	this->data[this->length] = '\0';
	// Last byte is 0x7E - ignore for now?
}

/**
 * Destructor.
 */
Frame::~Frame() {
	// TODO
}

/**
 * Convert this Frame to a string.
 */
char *Frame::toString() {
	char *str = (char *)malloc((FRAME_LEN + this->length + 1) * sizeof(char));
	str[0] = 0x7E;
	this->type == DATA ? memcpy(str+1, "0", 1) : memcpy(str+1, "1", 1);
	this->end ? memcpy(str+2, "1", 1) : memcpy(str+2, "0", 1);
	memcpy(str+3, stoa(this->seq, SEQ_NUM_LEN), SEQ_NUM_LEN);
	memcpy(str+8, stoa(this->ack, ACK_NUM_LEN), ACK_NUM_LEN);
	memcpy(str+13, ustoa(this->crc, CRC_LEN), CRC_LEN);
	memcpy(str+18, stoa(this->length, DATA_LEN), DATA_LEN);
	memcpy(str+21, this->data, this->length);
	str[21+this->length] = 0x7E;
	str[21+this->length+1] = '\0';

	return str;
}
